package com.cinc.ebc.sd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cinc.ebc.mm.entity.MmStockInOut;
import com.cinc.ebc.mm.entity.MmStockInOutDetail;
import com.cinc.ebc.mm.model.MmMaterialStockAllocateModel;
import com.cinc.ebc.mm.service.IMmMaterialStockService;
import com.cinc.ebc.mm.service.IMmStockInOutService;
import com.cinc.ebc.sd.constant.SdConstant;
import com.cinc.ebc.sd.entity.SdDispatchLoad;
import com.cinc.ebc.sd.entity.SdDispatchLoadDetail;
import com.cinc.ebc.sd.entity.SdDispatchNotice;
import com.cinc.ebc.sd.mapper.SdDispatchLoadDetailMapper;
import com.cinc.ebc.sd.mapper.SdDispatchLoadMapper;
import com.cinc.ebc.sd.mapper.SdDispatchNoticeMapper;
import com.cinc.ebc.sd.mapper.SdSalesOrderMapper;
import com.cinc.ebc.sd.model.SdDispatchLoadDetailOutModel;
import com.cinc.ebc.sd.service.ISdDispatchLoadService;
import com.cinc.ebc.sd.service.ISdDispatchNoticeService;
import com.cinc.ebc.sd.service.ISdSalesOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 装车单
 * @Author: jeecg-boot
 * @Date:   2022-09-25
 * @Version: V1.0
 */
@Service
public class SdDispatchLoadServiceImpl extends ServiceImpl<SdDispatchLoadMapper, SdDispatchLoad> implements ISdDispatchLoadService {

	@Autowired
	private SdDispatchLoadMapper sdDispatchLoadMapper;
	@Autowired
	private SdDispatchLoadDetailMapper sdDispatchLoadDetailMapper;

	@Autowired
	private ISdDispatchNoticeService sdDispatchNoticeService;

	@Autowired
	private SdDispatchNoticeMapper sdDispatchNoticeMapper;

	@Autowired
	private IMmMaterialStockService mmMaterialStockService;

	@Autowired
	private SdSalesOrderMapper sdSalesOrderMapper;

	@Autowired
	private ISdSalesOrderService sdSalesOrderService;

	@Autowired
	private IMmStockInOutService mmStockInOutService;

	@Override
	@Transactional
	public void saveMain(SdDispatchLoad sdDispatchLoad, List<SdDispatchLoadDetail> sdDispatchLoadDetailList) throws Exception {
		sdDispatchLoadMapper.insert(sdDispatchLoad);
		if(sdDispatchLoadDetailList!=null && sdDispatchLoadDetailList.size()>0) {
			for(SdDispatchLoadDetail entity:sdDispatchLoadDetailList) {
				//外键设置
				entity.setMainId(sdDispatchLoad.getId());
				sdDispatchLoadDetailMapper.insert(entity);
				// 更新库存分配
				MmMaterialStockAllocateModel materialStockAllocateModel = new MmMaterialStockAllocateModel();
				materialStockAllocateModel.setMaterialId(entity.getMaterialId());
				materialStockAllocateModel.setWarehouseId(entity.getWarehouseId());
				materialStockAllocateModel.setStorageLocationId(entity.getStorageLocationId());
				materialStockAllocateModel.setBatchNo(entity.getBatchNo());
				materialStockAllocateModel.setOldQty(BigDecimal.ZERO);
				materialStockAllocateModel.setNewQty(entity.getQty());
				mmMaterialStockService.updateStockAllocate(materialStockAllocateModel);
			}
			// 更新发货通知、销售单
			QueryWrapper<SdDispatchNotice> noticeQueryWrapper = new QueryWrapper<>();
			noticeQueryWrapper.in("notice_no", Arrays.asList(sdDispatchLoad.getNoticeNoJoin().split(",")));
			List<SdDispatchNotice> noticeList = sdDispatchNoticeMapper.selectList(noticeQueryWrapper);
			for(SdDispatchNotice notice : noticeList){
				// 发货通知单
				sdDispatchNoticeService.autoUpdateDispatchNotice(notice.getId());
				// 销售单
				sdSalesOrderService.autoUpdateSalesOrder(notice.getSalesOrderId());
			}
		}
	}

	@Override
	@Transactional
	public void updateMain(SdDispatchLoad sdDispatchLoad,List<SdDispatchLoadDetail> sdDispatchLoadDetailList) throws Exception {
		SdDispatchLoad sdDispatchLoadResponse = sdDispatchLoadMapper.selectById(sdDispatchLoad.getId());
		if(!SdConstant.SAL_LOAD_STATUS01.equals(sdDispatchLoadResponse.getStatus())){
			throw new RuntimeException("当前状态不能修改");
		}

		sdDispatchLoadMapper.updateById(sdDispatchLoad);

		List<SdDispatchLoadDetail> dispatchLoadDetailList = sdDispatchLoadDetailMapper.selectByMainId(sdDispatchLoad.getId());
		Map<String, BigDecimal> idAndQty = dispatchLoadDetailList.stream().collect(Collectors.toMap(SdDispatchLoadDetail::getId, SdDispatchLoadDetail::getQty));
		//1.先删除子表数据
		sdDispatchLoadDetailMapper.deleteByMainId(sdDispatchLoad.getId());

		//2.子表数据重新插入
		if(sdDispatchLoadDetailList!=null && sdDispatchLoadDetailList.size()>0) {
			for(SdDispatchLoadDetail entity:sdDispatchLoadDetailList) {
				//外键设置
				entity.setMainId(sdDispatchLoad.getId());
				sdDispatchLoadDetailMapper.insert(entity);
				// 更新库存分配
				MmMaterialStockAllocateModel materialStockAllocateModel = new MmMaterialStockAllocateModel();
				materialStockAllocateModel.setMaterialId(entity.getMaterialId());
				materialStockAllocateModel.setWarehouseId(entity.getWarehouseId());
				materialStockAllocateModel.setStorageLocationId(entity.getStorageLocationId());
				materialStockAllocateModel.setBatchNo(entity.getBatchNo());
				BigDecimal oldQty = idAndQty.get(entity.getId());
				materialStockAllocateModel.setOldQty(oldQty == null ? BigDecimal.ZERO:oldQty);
				materialStockAllocateModel.setNewQty(entity.getQty());
				mmMaterialStockService.updateStockAllocate(materialStockAllocateModel);
			}
		}
		// 更新发货通知、销售单
		QueryWrapper<SdDispatchNotice> noticeQueryWrapper = new QueryWrapper<>();
		noticeQueryWrapper.in("notice_no", Arrays.asList(sdDispatchLoad.getNoticeNoJoin().split(",")));
		List<SdDispatchNotice> noticeList = sdDispatchNoticeMapper.selectList(noticeQueryWrapper);
		for(SdDispatchNotice notice : noticeList){
			// 发货通知单
			sdDispatchNoticeService.autoUpdateDispatchNotice(notice.getId());
			// 销售单
			sdSalesOrderService.autoUpdateSalesOrder(notice.getSalesOrderId());
		}
	}

	@Override
	@Transactional
	public void delMain(String id) throws Exception {
		SdDispatchLoad sdDispatchLoad = sdDispatchLoadMapper.selectById(id);
		if(!SdConstant.SAL_LOAD_STATUS01.equals(sdDispatchLoad.getStatus())){
			throw new RuntimeException("当前状态不能删除");
		}
		List<SdDispatchLoadDetail> dispatchLoadDetailList = sdDispatchLoadDetailMapper.selectByMainId(sdDispatchLoad.getId());
		sdDispatchLoadDetailMapper.deleteByMainId(id);
		sdDispatchLoadMapper.deleteById(id);

		for(SdDispatchLoadDetail dispatchLoadDetail : dispatchLoadDetailList){
			// 更新库存分配
			MmMaterialStockAllocateModel materialStockAllocateModel = new MmMaterialStockAllocateModel();
			materialStockAllocateModel.setMaterialId(dispatchLoadDetail.getMaterialId());
			materialStockAllocateModel.setWarehouseId(dispatchLoadDetail.getWarehouseId());
			materialStockAllocateModel.setStorageLocationId(dispatchLoadDetail.getStorageLocationId());
			materialStockAllocateModel.setBatchNo(dispatchLoadDetail.getBatchNo());
			materialStockAllocateModel.setOldQty(dispatchLoadDetail.getQty());
			materialStockAllocateModel.setNewQty(BigDecimal.ZERO);
			mmMaterialStockService.updateStockAllocate(materialStockAllocateModel);
		}
		// 更新发货通知、销售单
		QueryWrapper<SdDispatchNotice> noticeQueryWrapper = new QueryWrapper<>();
		noticeQueryWrapper.in("notice_no", Arrays.asList(sdDispatchLoad.getNoticeNoJoin().split(",")));
		List<SdDispatchNotice> noticeList = sdDispatchNoticeMapper.selectList(noticeQueryWrapper);
		for(SdDispatchNotice notice : noticeList){
			// 发货通知单
			sdDispatchNoticeService.autoUpdateDispatchNotice(notice.getId());
			// 销售单
			sdSalesOrderService.autoUpdateSalesOrder(notice.getSalesOrderId());
		}
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) throws Exception {
		for(Serializable id:idList) {
			delMain(id.toString());
		}
	}

	/**
	 * 出库
	 * @param detailOutModelList
	 */
	@Override
	@Transactional
	public void handleOut(List<SdDispatchLoadDetailOutModel> detailOutModelList) throws Exception {
		List<MmStockInOutDetail> stockInOutDetailList = new ArrayList<>();
		int stockInOutDetaiLineNo = 0;
		// 获取客户列表、通知单列表
		List<String> customerIdList = new ArrayList<>();
		List<String> noticeNoList = new ArrayList<>();
		List<String> loadNoList = detailOutModelList.stream().map(SdDispatchLoadDetailOutModel::getLoadNo).distinct().collect(Collectors.toList());
		QueryWrapper<SdDispatchLoad> loadQuery = new QueryWrapper<>();
		loadQuery.in("load_no",loadNoList);
		List<SdDispatchLoad> sdDispatchLoadList = sdDispatchLoadMapper.selectList(loadQuery);
		for(SdDispatchLoad sdDispatchLoad : sdDispatchLoadList){
			if(!customerIdList.contains(sdDispatchLoad.getCustomerId())){
				customerIdList.add(sdDispatchLoad.getCustomerId());
			}
			List<String> tempNoticeNoList = Arrays.asList(sdDispatchLoad.getNoticeNoJoin().split(","));
			for(String noticeNo : tempNoticeNoList){
				if(!noticeNoList.contains(noticeNo)){
					noticeNoList.add(noticeNo);
				}
			}
		}
		// 按客户生成出库单
		for(String customerId : customerIdList) {
			String projectId = null;
			for (SdDispatchLoadDetailOutModel detailOutModel : detailOutModelList) {
				if (!detailOutModel.getCustomerId().equals(customerId)) {
					continue;
				}
				// 更新装车明细
				BigDecimal outQty = detailOutModel.getOutQty();
				if (outQty.compareTo(BigDecimal.ZERO) <= 0) {
					throw new RuntimeException("出库数量必须大于零");
				}
				SdDispatchLoadDetail dispatchLoadDetail = sdDispatchLoadDetailMapper.selectById(detailOutModel.getId());
				BigDecimal deliveryQty = dispatchLoadDetail.getDeliveryQty().add(outQty);
				if (deliveryQty.compareTo(dispatchLoadDetail.getQty()) == 1) {
					throw new RuntimeException("出库数量不能超出装车量;");
				}
				SdDispatchLoadDetail dispatchLoadDetailModify = new SdDispatchLoadDetail();
				dispatchLoadDetailModify.setId(detailOutModel.getId());
				dispatchLoadDetailModify.setDeliveryQty(deliveryQty);
				if (deliveryQty.compareTo(dispatchLoadDetail.getQty()) == 0) {
					dispatchLoadDetailModify.setStatus(SdConstant.SAL_LOADDETAIL_STATUS03);
				} else {
					dispatchLoadDetailModify.setStatus(SdConstant.SAL_LOADDETAIL_STATUS02);
				}
				sdDispatchLoadDetailMapper.updateById(dispatchLoadDetailModify);
				projectId = detailOutModel.getProjectId();
				// 出库单明细
				MmStockInOutDetail stockInOutDetail = new MmStockInOutDetail();
				stockInOutDetaiLineNo += 10;
				stockInOutDetail.setLineNo(stockInOutDetaiLineNo);
				stockInOutDetail.setMaterialId(dispatchLoadDetail.getMaterialId());
				stockInOutDetail.setMaterialNo(dispatchLoadDetail.getMaterialNo());
				stockInOutDetail.setMaterialDesc(dispatchLoadDetail.getMaterialDesc());
				stockInOutDetail.setUnit(dispatchLoadDetail.getUnit());
				stockInOutDetail.setQty(detailOutModel.getOutQty());
				stockInOutDetail.setUnitPrice(dispatchLoadDetail.getUnitPrice());
				BigDecimal sumPrice = dispatchLoadDetail.getUnitPrice().multiply(detailOutModel.getOutQty()).setScale(2, BigDecimal.ROUND_HALF_UP);
				stockInOutDetail.setSumPrice(sumPrice);
				stockInOutDetail.setSourceId(dispatchLoadDetail.getSalesDetailId());
				stockInOutDetail.setSourceNo(dispatchLoadDetail.getSalesOrderNo());
				stockInOutDetail.setWarehouseId(dispatchLoadDetail.getWarehouseId());
				stockInOutDetail.setStorageLocationId(dispatchLoadDetail.getStorageLocationId());
				stockInOutDetail.setBatchNo(dispatchLoadDetail.getBatchNo());
				stockInOutDetailList.add(stockInOutDetail);
			}
			// 生成出库单
			MmStockInOut stockInOut = new MmStockInOut();
			stockInOut.setBillDate(new Date());
			stockInOut.setCustomerId(customerId);
			stockInOut.setProjectId(projectId);
			mmStockInOutService.saveMainSalesOut(stockInOut, stockInOutDetailList, true);
		}
		// 更新发货通知、销售单
		QueryWrapper<SdDispatchNotice> noticeQueryWrapper = new QueryWrapper<>();
		noticeQueryWrapper.in("notice_no", noticeNoList);
		List<SdDispatchNotice> noticeList = sdDispatchNoticeMapper.selectList(noticeQueryWrapper);
		for(SdDispatchNotice notice : noticeList){
			// 发货通知单
			sdDispatchNoticeService.autoUpdateDispatchNotice(notice.getId());
			// 销售单
			sdSalesOrderService.autoUpdateSalesOrder(notice.getSalesOrderId());
		}
	}

}
